<?php
declare (strict_types=1);

namespace app\admin\controller\dev;

use app\admin\annotation\common\Auth;
use app\admin\controller\Admin;
use app\admin\model\dev\Api as ApiModel;
use app\admin\service\common\SortableService;
use app\admin\validate\dev\Api as ApiValidate;
use app\admin\model\admin\I18n as I18nModel;
use app\admin\service\dev\ApiService;
use app\common\Constants;
use app\common\facade\StrHelper;
use think\facade\Log;

class Api extends Admin
{

    /**
     * 菜单列表
     * @return \think\response\Json
     */
    #[Auth('dev:api:index')]
    public function index(): \think\response\Json
    {

        $params = $this->request->post();
        validate(ApiValidate::class)
            ->scene('index')
            ->check($params);
        $query = ApiModel::withPerms();

        $query->when(isset($params['role_id']), function ($query) use ($params) {
            $keyword = str_replace(['%', '_'], ['\%', '\_'], $params['keyword']);
            $query->where('name|controller|remark', 'like', "%" . $keyword . "%");
        });

        $order_by = sort_rules($params['order_by'] ?? 'sort|desc');
        $query->order($order_by);

        $page_size = $params['page_size'] ?? 99999;
        $current_page = $params['current_page'] ?? 1;
        $list = $query->paginate(['list_rows' => $page_size, 'page' => $current_page])->toArray();

        $list['sort'] = $order_by;
        return $this->success(['data' => $list]);

    }


    /**
     * 添加菜单数据
     *
     * @return \think\response\Json
     */
    #[Auth('dev:api:add')]
    public function add(): \think\response\Json
    {
        try {
            $post = $this->request->post();
            validate(ApiValidate::class)
                ->scene('add')
                ->check($post);
            $menu_id = ApiService::addApi($post);
            return $this->success(['data' => $menu_id]);
        } catch (\think\Exception\ValidateException $ve) {
            return $this->error(['message' => $ve->getMessage()]);
        } catch (\Exception $e) {
            throw $e;
        }
    }

    /**
     * 用于更新的数据
     * @return \think\response\Json
     */
    #[Auth('dev:api:update')]
    public function getFormData(): \think\response\Json
    {

        $id = $this->request->param('id');
        if (!$id) {
            return $this->error(['msg' => Constants::E_COMMON_INVALID_PARAM]);
        }
        $result = ApiModel::find($id)->toArray();
        if (!$result) {
            return $this->error(['msg' => Constants::E_COMMON_RECORD_NOT_FOUND]);
        }
        // 根据多语言key获取多语言翻译数据
        if ($result['key']) {
            $result['translations'] = I18nModel::where('key', $result['key'])->column('value', 'lang_code');
        }
        return $this->success(['data' => $result]);

    }

    /**
     * 更新菜单数据
     * @return \think\response\Json
     */
    #[Auth('dev:api:update')]
    public function update()
    {
        try {
            $post = $this->request->post();
            validate(ApiValidate::class)
                ->scene('update')
                ->check($post);
            ApiService::updateApi($post);
            return $this->success();
        } catch (\think\Exception\ValidateException $ve) {
            return $this->error(['msg' => $ve->getMessage()]);
        } catch (\Exception $e) {
            throw $e;
        }
    }


    /**
     * 获得菜单详情数据
     * @return \think\response\Json
     */
    #[Auth('dev:api:detail')]
    public function detail(): \think\response\Json
    {

        $id = $this->request->param('id');
        if (!$id) {
            return $this->error(['msg' => Constants::E_COMMON_INVALID_PARAM]);
        }
        $result = ApiModel::with('parent')->find($id)->toArray();
        if (!$result) {
            return $this->error(['msg' => Constants::E_COMMON_RECORD_NOT_FOUND]);
        }
        if ($result['key']) {
            $result['translations'] = I18nModel::where('key', $result['key'])->column('value', 'lang_code');
        }
        return $this->success(['data' => $result]);

    }


    /**
     * 删除菜单数据
     * @return \think\response\Json
     */
    #[Auth('dev:api:delete')]
    public function delete(): \think\response\Json
    {

        $id = $this->request->post('id');
        if (empty($id)) {
            return $this->error(['msg' => Constants::E_COMMON_INVALID_PARAM]);
        }
        ApiService::deleteApi($id);
        return $this->success();

    }


    /**
     *  拖拽排序
     * @return \think\response\Json
     */
    #[Auth('dev:api:drag')]
    public function drag(): \think\response\Json
    {

        $fields = "newId,oldId,dragPos,orderBy,dragToChild";
        $data = $this->request->only(explode(',', $fields), 'post');
        SortableService::treeSort('dev_api', $data);
        return $this->success();

    }


    /**
     * 修改任意字段
     * @return \think\response\Json
     */
    #[Auth('dev:api:modify')]
    public function modify(): \think\response\Json
    {

        $post = $this->request->post();
        $keys = array_keys($post);
        $array = array_values(array_filter($keys, fn($v) => $v !== 'id'));
        $field = $array[0];
        if (!$post['id']) {
            return $this->error(['msg' => Constants::E_COMMON_INVALID_PARAM]);
        }
        if (!in_array($field, ['status', 'gen_table', 'gen_code', 'visible','remark'])) {
            return $this->error(['msg' => Constants::E_COMMON_FORBIDDEN]);
        }
        $model = ApiModel::find($post['id']);
        if ($model['type'] != Constants::MENU_TYPE_MENU) {
            return $this->error(['msg' => Constants::E_COMMON_FORBIDDEN]);
        }
        if (!$model) {
            return $this->error(['msg' => Constants::E_COMMON_RECORD_NOT_FOUND]);
        }
        $model[$field] = $post[$field];
        $result = $model->save();
        if (!$result) {
            throw new \Exception('更新状态失败');
        }
        return $this->success();

    }

    /**
     * 生成代码
     * @return \think\response\Json
     */
    #[Auth('dev:api:gen_code')]
    public function genCode()
    {
        // 菜单id
        $menu_id = $this->request->post('id/d');
        $overwrite = $this->request->post('overwrite/b');
        // 生成代码
        $data = ApiService::genCodeHandle($menu_id, $overwrite);
        // 返回结果
        return $this->success(['data' => $data]);
    }


    /**
     * 生成接口文档
     * @return \think\response\Json
     */
    #[Auth('dev:api:gen_docs')]
    public function genDocs(): \think\response\Json
    {
        $paths[] = root_path('app') . 'common' . DIRECTORY_SEPARATOR . 'model';
        $paths[] = root_path('app') . 'api' . DIRECTORY_SEPARATOR . 'model';
        $paths[] = root_path('app') . 'api' . DIRECTORY_SEPARATOR . 'validate';
        $paths[] = root_path('app') . 'api' . DIRECTORY_SEPARATOR . 'controller';
        $scan_paths = [];
        foreach ($paths as $path) {
            if(is_dir($path)){
                $scan_paths[] = $path;
            }
        }
        $openapi = \OpenApi\Generator::scan($scan_paths);
        $filePath = public_path() . DIRECTORY_SEPARATOR . 'docs' . DIRECTORY_SEPARATOR . 'swagger.json';
        file_put_contents($filePath, $openapi->toJson());
        return $this->success();
    }


    /**
     * 获取字典数据
     * @return \think\response\Json
     */
    public function getConnects(): \think\response\Json
    {
        // 数据库连接
        $connects = [];
        foreach (config('database.connections') as $k => $v) {
            $connects[] = ['label' => strtoupper($k), 'value' => $k];
        }
        return $this->success(['data' => $connects]);
    }

    /**
     * 根据菜单id获得此菜单的权限前缀
     * @return \think\response\Json
     */
    public function getPermPrefix(): \think\response\Json
    {

        $menu_id = $this->request->post('menu_id', null, 'intval');
        $menu_info = ApiModel::find($menu_id);
        $prefix = ApiService::convertToPermissionPrefix($menu_info['controller']);

        return $this->success(['data' => $prefix]);
    }




}